package gbench.appdemo.priceline.app;

import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

import gbench.appdemo.priceline.indicator.OHLC;
import gbench.appdemo.priceline.model.PeriodPriceLineModel;
import gbench.common.tree.LittleTree.IRecord;
import gbench.common.tree.LittleTree.Jdbc;
import gbench.commonApp.data.DataApp;

import static gbench.common.tree.LittleTree.IRecord.*;
import static gbench.common.tree.LittleTree.*;

/**
 * 
 * @author gbench
 *
 */
public class JunitKLineModel {
    
    public class MyData extends DataApp{
        public List<IRecord> sqlquery(final String sql) {
            cfg.set("url", "jdbc:mysql://localhost:3306/futures?serverTimezone=GMT%2B8"); reload();
            return this.jdbc.sql2records(sql);
        }
        
        public IRecord config() {
            cfg.set("url", "jdbc:mysql://localhost:3306/futures?serverTimezone=GMT%2B8"); reload();
            return this.cfg;
        }
    }
    
    @Test
    public void foo() {
        final var ticker = "mpg001";
        final var dataApp = new MyData();
        final var redisData = new ConcurrentHashMap<String,List<IRecord>>();// 数据缓存,模拟redis数据库
        final var klineDatabase = new ConcurrentHashMap<String,LinkedHashMap<Long,OHLC>>();// K线数据
        final BiFunction<String,Number,String> kdb_key = (_ticker,period)->MFT("{0}/{1,number,#}",_ticker,period);
        final var klineModel = KLineModel.newInstance(REC(
            "ticker",ticker,
            "periods",A(60000,300000),
            "redis_data",redisData,
            "jdbc",Jdbc.M("url", "jdbc:mysql://localhost:3306/futures?serverTimezone=GMT%2B8", 
                "driver", "com.mysql.cj.jdbc.Driver","user", "root","password", "123456"), // jdbc 数据库配置
            "inner_callback",(BiConsumer<PeriodPriceLineModel<OHLC>.PeriodPriceLineProcessor,OHLC>) (p,ohlc)->{
                klineDatabase.compute(kdb_key.apply(p.getTicker(),p.getPeriod()), (k, k2ohlcs) -> { // K线数据库的读写 (tiker
                    if(k2ohlcs==null) k2ohlcs = new LinkedHashMap<Long,OHLC>(); // 寻找ticker map 数据
                    k2ohlcs.compute(ohlc.getIndex(), (idx,_ohlc) -> {
                        return _ohlc == null
                        ? ohlc
                        : _ohlc.getTime().isBefore(ohlc.getTime()) ? ohlc : ohlc; // 更新数据记录
                    });// index
                    return k2ohlcs;
                });// ticker,period
                System.out.println(ohlc);
            }
        ));
        
        //准备初始数据
        dataApp.sqlquery("SELECT time, price, volume FROM ohlc1.t_deriv_eg2001 limit 10000").forEach(klineModel::handle);
        klineModel.flush();// 刷新数据到数据库，持久保存
        
        //多次查询
        for(int i=0;i<10000;i++) {
            System.out.println(MFT("\n第{0,number,#}次:",i+1));
            klineModel.getPriceline(ticker, 60000, 0, 10).forEach(System.out::println);
        }
        
        // 倾倒redis缓存数据
        System.out.println("\n----------------------处理日志----------------------------");
        redisData.forEach((k,recs)->System.out.println(MFT("\n{0}:\n{1}",k,IRecord.FMT(recs.subList(0, Math.min(recs.size(),1000))))));
        System.out.println("\n----------------------日志大小----------------------------");
        redisData.forEach((k,recs)->System.out.println(k+":"+recs.size()));
        System.out.println("\n----------------------K线数据----------------------------");
        klineDatabase.forEach((k,ohlcs)->{
            final var priceline = ohlcs.values().stream().map(IRecord::OBJ2REC).collect(Collectors.toList());
            System.out.println(k);
            System.out.println(IRecord.FMT(priceline));
        });
    }

}
